package com.turtle3d.user.grammars;

import com.turtle3d.Randomizer;
import com.turtle3d.formallanguage.grammar.Grammar;
import com.turtle3d.formallanguage.grammar.parser.SimpleParser;
import com.turtle3d.formallanguage.symbol.Method;
import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.formallanguage.symbol.SymbolClass;
import com.turtle3d.formallanguage.symbol.SymbolFactory;

public class Tree extends Grammar
{
	
	public Tree(){
		
	}
	
	public void define(){
		
		Symbol axiom = new Symbol("B");		
		setAxiom(axiom);
		
		SymbolClass radiusGrowth = new SymbolClass("F", "F(r*1.8)");		
		radiusGrowth.addMethod(new Method(){
			public boolean calculate(Symbol removedSymbol, Symbol calculatedSymbol)
			{
				Float r = removedSymbol.getParameter("radius");
				Float r_mul = removedSymbol.getParameter("radiusMultiplier");
				calculatedSymbol.setParameter("radius", r*r_mul);
				
				Float d = removedSymbol.getParameter("distance");
				Float d_mul = removedSymbol.getParameter("distanceMultiplier");
				calculatedSymbol.setParameter("distance", d*d_mul);
				
				return true;
				
			}
		});				
		SymbolFactory.getSymbolFactory().registerSymbolClass(radiusGrowth);
		SymbolClass bClass = new SymbolClass("B","B");
		bClass.addMethod(new Method(){
			public boolean calculate(Symbol removedSymbol, Symbol calculatedSymbol)
			{
				float i = calculatedSymbol.getBirthIteration();
				float iC = calculatedSymbol.getParameter("iterationsCount");
				float branchChance = calculatedSymbol.getParameter("branchChance");
				
				return Randomizer.getRandomizer().getRandom().nextFloat()<( (i+branchChance*iC)/iC);
				//return true;
			}			
		});
		SymbolFactory.getSymbolFactory().registerSymbolClass(bClass);
		
		addProduction(SimpleParser.parseProduction("B->F[+RB][-RB][<+RB][>+RB]"));
		addProduction(SimpleParser.parseProduction("F->F(r*1.8)"));
		
		initDefaultParameters();
						
	}
	
	public void initDefaultParameters(){
		setDefaultParameter("radius", 0.02f);
		setDefaultParameter("radiusMultiplier", 1.6f);
		setDefaultParameter("distance", 0.2f);
		setDefaultParameter("distanceMultiplier", 1.5f);		
		setDefaultParameter("spreadVariation", 5f);
		setDefaultParameter("turnAngle", 30f);
		setDefaultParameter("branchChance", 0.6f);
	}

}
